package com.surfilter.platform.base.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.surfilter.platform.base.exception.CustomException;
import com.surfilter.platform.base.exception.ExceptionBase;
import com.surfilter.platform.base.model.ConditionBase;
import com.surfilter.platform.base.model.MethodWrap;
import com.surfilter.platform.base.model.ModelBase;
import com.surfilter.platform.base.model.ParameterClassType;
import com.surfilter.platform.base.model.ParameterInfoModel;

public class MethodUtil {
	private static Logger logger = Logger.getLogger(ExceptionBase.LOG_SYSTEM);

	public static Object InvokeServiceMethod(Object serviceObject,
			MethodWrap methodWrap, HttpServletRequest request,HttpServletResponse response) throws Throwable {
			Method method = methodWrap.getMethod();
			Object retObject = null;
			method.setAccessible(true);

			Class[] types = method.getParameterTypes();

			int length = types.length;

			Object[] args = new Object[types.length];
			int c = 0;
			for (Class type : types) {

				String paramValue = null;
				String[] paramValues = null;
				ParameterClassType mapType = ParameterClassType.NORMAL;
				Class componentType = type.getComponentType();

				// 获取方法参数映射关系
				ParameterInfoModel piModel = methodWrap.getParameterMapInfo(c);

				if (piModel != null) {
					String mapName = piModel.getMapName();
					mapType = piModel.getMapType();
					componentType = (componentType == null) ? piModel
							.getComponentType() : componentType;
					if (mapType == ParameterClassType.ARRAY) {
						paramValues = request.getParameterValues(mapName);
					} else {
						paramValue = request.getParameter(mapName);
					}
				}

				// 基础类型自动映射
				if (ObjectUtil.isBasicClass(type)) {
					args[c] = ObjectUtil.getBasicObjectValue(type, paramValue);
				}
				// request直传入接口
				else if (ServletRequest.class.isAssignableFrom(type)) {
					args[c] = request;
				}
				
				else if(ServletResponse.class.isAssignableFrom(type)){
					args[c] = response;
				}
				// 基础数据模型
				else if (ModelBase.class.isAssignableFrom(type)) {
					// Normal或JsonObject
					if (mapType == ParameterClassType.JSONOBJECT) {
						Object paramObject = ObjectUtil
								.getObjectBeanFromJsonObjectString(type,
										paramValue);
						args[c] = paramObject;
					} else if(ConditionBase.class.isAssignableFrom(type)){
						Object paramObject = ConditionBase.getCondition(request, type);
						args[c] = paramObject;
					} else{
						Object paramObject = ObjectUtil
								.getObjectBeanFromRequest(type.newInstance(),
										request);
						args[c] = paramObject;
					}
				}
				// 数组
				else if (type.isArray()) {
					// jsonArray 或者  Array
					if (componentType == null) {
						args[c] = null;
					} else if (paramValues != null
							&& mapType == ParameterClassType.ARRAY) {
						Object arr = ObjectUtil
								.transferStringArrayToObjectArray(
										componentType, paramValues);
						args[c] = arr;
					} else if (paramValue != null
							&& mapType == ParameterClassType.JSONARRAY) {
						Object arr = ObjectUtil
								.getObjectArrayFromJsonArrayString(
										componentType, paramValue);
						args[c] = arr;
					} else {
						args[c] = null;
					}
				}
				// 集合
				else if (Collection.class.isAssignableFrom(type)) {
					// jsonArray 或者 Array
					if (componentType == null) {
						args[c] = null;
					} else if (paramValues != null
							&& mapType == ParameterClassType.ARRAY) {
						Object arr = ObjectUtil
								.transferStringArrayToObjectCollection(
										componentType, paramValues, type);
						args[c] = arr;
					} else if (paramValue != null
							&& mapType == ParameterClassType.JSONARRAY) {
						Object arr = ObjectUtil
								.getObjectCollectionFromJsonArrayString(
										componentType, paramValue, type);
						args[c] = arr;
					} else {
						args[c] = null;
					}
				} else {
					args[c] = null;
				}
				c++;
			}
			try {
				retObject = method.invoke(serviceObject, args);
			} catch (InvocationTargetException e) {
				throw e.getTargetException();
			} 
			return retObject;
		
	}
}
